﻿using System;
using System.Collections;

using BizElements.Core;

namespace BizElements.BusinessLayer
{
    /// <summary>Generic interface for managing children collections that belong to a composite entity object.</summary>
    public interface IChildrenAdapter
    {
        /// <summary>Child collection property name.</summary>
        string PropertyName { get; }

        /// <summary>Gets relation through which child entities are connected to parent table.</summary>
        /// <returns>Database relation.</returns>
        DbRelation GetForeignKey();

        /// <summary>Gets child collection that belongs to the specified parent entity.</summary>
        /// <param name="parentEntity">Parent object that owns the child collection worked by current adapter.</param>
        /// <returns>Children entity collection.</returns>
        IList GetChildren(IBusinessObject parentEntity);

        /// <summary>Fetches children that belong to the specified parent entity from data source.</summary>
        /// <param name="parentEntity">Parent object that owns the child collection wrapped by the current adapter.</param>
        void FetchChildren(IBusinessObject parentEntity);

        /// <summary>Ensures that the child collection has been fetched from data source.</summary>
        /// <param name="parentEntity">Parent object that owns the child collection wrapped by the current adapter.</param>
        void EnsureChildren(IBusinessObject parentEntity);

        /// <summary>Persists children to data source if partial saving of composite entity is allowed and implemented by provided composite entity.</summary>
        /// <param name="parentEntity">Parent object that owns the child collection wrapped by the current adapter.</param>
        /// <param name="actionInitiator">Action initiator. This may be an application user, software module, 3rd party application etc. which is initiating the save action. <b>Null</b> is not allowed.</param>
        /// <param name="enforceSecurityChecks">Indicates whether the actor's permissions to save the current object are to be checked. Set to <b>false</b> only if client is trusted and the security checks have been executed elsewhere.</param>
        /// <exception cref="BrokenRuleException">The given actor failed the security checks. Generated exception contains details about broken rules/permissions.</exception>
        void SaveChildren(IBusinessObject parentEntity, IActor actionInitiator, bool enforceSecurityChecks);

        /// <summary>Validates child entities that belong to the specified parent entity if partial validation of composite entity is allowed and implemented.</summary>
        /// <param name="parentEntity">Parent object that owns the child collection wrapped by the current adapter.</param>
        /// <param name="level">Specifies the detail of validation.</param>
        /// <returns>Collection of broken rules.</returns>
        BusinessRuleCollection ValidateChildren(IBusinessObject parentEntity, ValidationLevel level);

        /// <summary>Creates a new instance of child entity but it's not automatically added to the collection.</summary>
        /// <param name="parentEntity">Parent object that owns the child collection wrapped by the current adapter.</param>
        /// <param name="createdBy">Actor that creates a new object.</param>
        /// <returns>A child entity.</returns>
        IDataObject NewChild(IBusinessObject parentEntity, IActor createdBy);

        /// <summary>Ensures that child collection contains objects that implement <see cref="IDataObject"/> interface. The method will attempt to convert simple, BizElements generated, entities to business objects.</summary>
        /// <param name="parentEntity">Parent object that owns the child collection wrapped by the current adapter.</param>
        void EnsureBusinessObjectsInChildCollection(IBusinessObject parentEntity);

        /// <summary>Ensures that all parent entities for children are initialized, ie. fetched.</summary>
        /// <param name="parentEntity">Parent object that owns the child collection wrapped by the current adapter.</param>
        void EnsureAllParentsForChildren(IBusinessObject parentEntity);

        /// <summary>Ensures that all specified parent entities for children are fetched, ie. fetched.</summary>
        /// <param name="parentEntity">Parent object that owns the child collection wrapped by the current adapter.</param>
        /// <param name="relationsToOtherParents">Relations to other parents.</param>
        void EnsureParentsForChildren(IBusinessObject parentEntity, DbRelation[] relationsToOtherParents);

        /// <summary>Creates a new adapter that is a copy of the current instance.</summary>
        /// <returns>A new object that is a copy of the current instance.</returns>
        IChildrenAdapter Clone();
    }
}